package org.autumn.review.thread;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

@Slf4j
public class TestGuardedSuspend {
    public static void main(String[] args) {
        GuardedObject guarded = new GuardedObject();

        Thread t1 = new Thread(() -> {
            try {
                Object response = guarded.getResponse(1000);
                log.info("response -> {}", response);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t1");
        t1.start();

        Thread t2 = new Thread(() -> {
            try {
                TimeUnit.SECONDS.sleep(3);
                guarded.setResponse("siru");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t2");
        t2.start();

    }
}


@Slf4j
class GuardedObject {
    Object o;

    public Object getResponse() throws InterruptedException {
        synchronized (this) {
            while (o == null) {
                this.wait();
            }
            return o;
        }
    }


    public Object getResponse(long timeout) throws InterruptedException {
        synchronized (this) {
            long begin = System.currentTimeMillis();
            long passedTime = 0;
            while (o == null) {
                if (passedTime >= timeout){
                    break;
                }
                this.wait(timeout - passedTime);

                passedTime = System.currentTimeMillis() - begin;
            }
            return o;
        }
    }

    public void setResponse(Object o) throws InterruptedException {
        synchronized (this) {
            log.info("set response -> {}", o);
            this.o = o;
            this.notifyAll();
        }
    }
}